package cn.terminus.service.customer.customreceive;

import cn.terminus.biz.customer.customreceive.CustomReceiveManager;
import cn.terminus.client.customer.customreceive.param.*;
import cn.terminus.client.customer.customreceive.result.CustomReceiveResult;
import cn.terminus.client.customer.customreceive.result.CustomReceiveZgResult;
import cn.terminus.client.customer.customreceive.service.CustomReceiveService;
import cn.terminus.common.customer.bean.customreceive.dto.*;
import cn.terminus.common.customer.constant.CustomReceiveStatusEnum;
import cn.terminus.result.common.annotation.TerminusParamVilidator;
import cn.terminus.result.common.context.TerminusCallContext;
import cn.terminus.result.common.exception.DataAccessException;
import cn.terminus.result.common.exception.ServiceException;
import cn.terminus.result.common.page.TerminusPageAble;
import cn.terminus.result.common.page.TerminusPageInfo;
import cn.terminus.result.common.result.TerminusResult;
import cn.terminus.result.common.util.BeanCopyUtils;
import cn.terminus.service.customer.common.AbstractTerminusService;
import cn.terminus.service.customer.feign.carrier.CarrierFeignClient;
import cn.terminus.service.customer.feign.carrier.ProjectInfoGetsParam;
import cn.terminus.service.customer.feign.carrier.ProjectListResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * (CustomReceive)表服务实现类
 *
 * @author makejava
 * @since 2021-08-12 10:27:51
 */
@Service
public class CustomReceiveServiceImpl extends AbstractTerminusService implements CustomReceiveService {
    /**
     * 日志
     */
    protected final Logger logger = LoggerFactory.getLogger(getClass());
    @Resource
    private CustomReceiveManager customReceiveManager;

    @Resource
    CarrierFeignClient carrierFeignClient;

    @Value("${customReceive.timeoutDay.zg}")
    private Integer timeOutDayWithZg;


    /**
     * 新增
     *
     * @param param
     * @param context
     * @return
     * @throws ServiceException
     */
    @Override
    @TerminusParamVilidator(argsIndexs = {0, 1})
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public TerminusResult<String> add(CustomReceiveNewParam param, TerminusCallContext context) throws ServiceException {
        CustomReceiveNewDto newDto = new CustomReceiveNewDto();
        newDto.setId(genUUID());
        BeanCopyUtils.copyProperties(param, context, newDto);
        try {
            customReceiveManager.add(newDto);
        } catch (DataAccessException e) {
            logger.error("新增失败,错误信息：{}", e.getMessage());
            throw new ServiceException(e);
        }
        return TerminusResult.success(String.valueOf(newDto.getId()));
    }

    /**
     * 更新
     *
     * @param param
     * @param context
     * @return
     * @throws ServiceException
     */
    @Override
    @TerminusParamVilidator(argsIndexs = {0, 1})
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public TerminusResult<Boolean> update(CustomReceiveEditParam param, TerminusCallContext context) throws ServiceException {
        CustomReceiveEditDto editDto = new CustomReceiveEditDto();
        BeanCopyUtils.copyProperties(param, context, editDto);
        try {
            customReceiveManager.update(editDto);
        } catch (DataAccessException e) {
            logger.error("更新失败,错误信息：{}", e.getMessage());
            throw new ServiceException(e);
        }
        return TerminusResult.success(true);
    }

    /**
     * 删除
     *
     * @param param
     * @param context
     * @return
     * @throws ServiceException
     */
    @Override
    @TerminusParamVilidator(argsIndexs = {0, 1})
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public TerminusResult<Boolean> delete(CustomReceiveDeleteParam param, TerminusCallContext context) throws ServiceException {
        CustomReceiveDeleteDto deleteDto = new CustomReceiveDeleteDto();
        BeanCopyUtils.copyProperties(param, context, deleteDto);
        try {
            customReceiveManager.delete(deleteDto);
        } catch (DataAccessException e) {
            logger.error("删除失败,错误信息：{}", e.getMessage());
            throw new ServiceException(e);
        }
        return TerminusResult.success(true);
    }


    /**
     * 查询
     *
     * @param param
     * @param context
     * @return
     * @throws ServiceException
     */
    @Override
    @TerminusParamVilidator(argsIndexs = {0, 1})
    public TerminusResult<List<CustomReceiveResult>> query(CustomReceiveQueryParam param, TerminusCallContext context) throws ServiceException {
        CustomReceiveQueryDto queryDto = new CustomReceiveQueryDto();
        BeanCopyUtils.copyProperties(param, queryDto);
        try {
            List<CustomReceiveResultDto> queryResultList = customReceiveManager.query(queryDto);
            return TerminusResult.success(BeanCopyUtils.copy(queryResultList, CustomReceiveResult.class));
        } catch (DataAccessException e) {
            logger.error("查询失败,错误信息：{}", e.getMessage());
            throw new ServiceException(e);
        }

    }

    /**
     * 查询
     *
     * @param param
     * @param context
     * @return
     * @throws ServiceException
     */
    @Override
    @TerminusParamVilidator(argsIndexs = {0, 1})
    public TerminusResult<List<CustomReceiveResult>> gets(CustomReceiveGetsParam param, TerminusCallContext context) throws ServiceException {
        CustomReceiveGetsDto getsDto = new CustomReceiveGetsDto();
        BeanCopyUtils.copyProperties(param, getsDto);
        try {
            List<CustomReceiveResultDto> getsResultList = customReceiveManager.gets(getsDto);
            return TerminusResult.success(BeanCopyUtils.copy(getsResultList, CustomReceiveResult.class));
        } catch (DataAccessException e) {
            logger.error("查询失败,错误信息：{}", e.getMessage());
            throw new ServiceException(e);
        }
    }

    /**
     * 分页查询
     *
     * @param param
     * @param context
     * @return
     * @throws ServiceException
     */
    @Override
    @TerminusParamVilidator(argsIndexs = {0, 1})
    public TerminusResult<TerminusPageAble<CustomReceiveZgResult>> page(CustomReceiveQueryParam param, TerminusPageInfo page, TerminusCallContext context) throws ServiceException {
        CustomPageQueryDto queryDto = new CustomPageQueryDto();
        BeanCopyUtils.queryCopyProperties(param,context, queryDto);
        queryDto.setCboChannelSource("1");
        try {
            TerminusPageAble<CustomReceiveResultDto> TerminusPageAble = customReceiveManager.page(queryDto, page);
            if (CollectionUtils.isEmpty(TerminusPageAble.getDatas())) {
                return TerminusResult.success(new TerminusPageAble<>(new ArrayList<>(), page, 0));
            }

            List<CustomReceiveResult> results = BeanCopyUtils.copy(TerminusPageAble.getDatas(), CustomReceiveResult.class);
            List<CustomReceiveZgResult> receiveZgResults = BeanCopyUtils.copy(results, CustomReceiveZgResult.class);
            List<Long> projectIds = receiveZgResults
                    .stream()
                    .map(CustomReceiveZgResult::getCboProjectId)
                    .distinct()
                    .collect(Collectors.toList());
            Map<Long, String> projectNameMap = null;
            if (!CollectionUtils.isEmpty(projectIds)) {
                ProjectInfoGetsParam projectInfoGetsParam = new ProjectInfoGetsParam();
                projectInfoGetsParam.setIds(projectIds);
                TerminusResult<List<ProjectListResult>> projectResult = carrierFeignClient.gets(projectInfoGetsParam);
                if (projectResult.isSuccess() && projectResult.getData() != null && projectResult.getData().size() > 0) {
                    projectNameMap = projectResult.getData().stream()
                            .collect(Collectors.toMap(ProjectListResult::getId, ProjectListResult::getCboProjectName));
                }
            }

            Map<Long, String> finalProjectNameMap = projectNameMap;
            receiveZgResults.forEach(r -> {
                String projectName = finalProjectNameMap.get(r.getCboProjectId());
                if (projectName != null) {
                    r.setProjectName(projectName);
                }
            });

            return TerminusResult.success(new TerminusPageAble<>(receiveZgResults,
                    page, TerminusPageAble.getTotalRows()));
        } catch (DataAccessException e) {
            logger.error("分页查询失败,错误信息：{}", e.getMessage());
            throw new ServiceException(e);
        }

    }

    @Override
    public TerminusResult<Boolean> batchConfig(BatchConfigParam param) throws ServiceException {

        BatchConfigDto configDto = new BatchConfigDto();
        BeanCopyUtils.copyProperties(param, configDto);
        try {
            Boolean flag = checkStatus(param.getIds());
            if(flag){
                return TerminusResult.fail("410020",this.getMessage("410020"));
            }

            customReceiveManager.batchConfig(configDto);
            return TerminusResult.success(true);
        } catch (DataAccessException e) {
            logger.error("查询失败,错误信息：{}", e.getMessage());
            throw new ServiceException(e);
        }
    }

    private Boolean checkStatus(List<Long> ids) throws DataAccessException {
        CustomReceiveGetsDto getsDto = new CustomReceiveGetsDto();
        getsDto.setIds(ids);
        List<CustomReceiveResultDto> resultDtos = customReceiveManager.gets(getsDto);

        if (resultDtos != null) {
            List<CustomReceiveResultDto> result = resultDtos
                    .stream()
                    .filter(c -> {
                        Integer status = c.getStatus();
                        return status != 0;
                    }).collect(Collectors.toList());
            return !CollectionUtils.isEmpty(result);
        }
        return false;
    }

    @Override
    public TerminusResult<Boolean> insertBatch(List<CustomReceiveNewParam> param) throws ServiceException {
        List<CustomReceiveNewDto> receiveNewDtoList = param.stream().map(p -> {
            CustomReceiveNewDto newDto = new CustomReceiveNewDto();
            BeanCopyUtils.copyProperties(p, newDto);
            newDto.setId(genUUID());
            newDto.setStatus(CustomReceiveStatusEnum.INIT.getCode());
            return newDto;
        }).collect(Collectors.toList());

        try {
            customReceiveManager.insertBatch(receiveNewDtoList);
        } catch (DataAccessException e) {
            logger.error("新增失败,错误信息：{}", e.getMessage());
            throw new ServiceException(e);
        }
        return TerminusResult.success(true);

    }
}
